package com.ch999.comparedata.hander;

import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import com.ch999.comparedata.entity.SQLUndoLog;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.update.Update;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;

import javax.sql.DataSource;
import java.io.StringReader;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class UpdateHander  extends AbstractHandler {

    private Update update;
    List<SQLUndoLog> sqlUndoLogList = new ArrayList<>();

    public UpdateHander(Statement statement, DataSource dataSource, String dataSourceType) {
        super(statement, dataSource,dataSourceType);
        update = (Update)statement;
    }


    @Override
    public void preHandle() throws Throwable {
        String tableName = update.getTables().get(0).getName();
        String executeSql = String.format(getExecuteSql(dataSourceType),tableName,update.getWhere().toString());
        List<Entity> result = Db.use(dataSource).query(executeSql);
        for (Entity entity:result){
            SQLUndoLog sqlUndoLog = new SQLUndoLog();
            sqlUndoLog.setBeforeImage(entity);
            sqlUndoLog.setSqlCommandType(SqlCommandType.UPDATE);
            sqlUndoLog.setTableName(tableName);
            sqlUndoLogList.add(sqlUndoLog);
        }

    }

    @Override
    public void postHandle() throws  SQLException {
        for (SQLUndoLog sqlUndoLog:sqlUndoLogList){
            Entity entity = (Entity) sqlUndoLog.getBeforeImage();
            String executeSql = String.format(getExecuteSql(dataSourceType),sqlUndoLog.getTableName(),"id = "+entity.get("id"));
            List<Entity> result = Db.use(dataSource).query(executeSql);
            sqlUndoLog.setAfterImage(result.get(0));
            sqlUndoLog.setTableName(sqlUndoLog.getTableName());
            String col = getColUpdate(update,entity);
            String resetSql = String.format(updateSql,sqlUndoLog.getTableName(),col,entity.get("id"));
            //保存日志
            addUndoLog(sqlUndoLog,resetSql);
        }
    }

    private String getColUpdate(Update update,Entity entity){
        List<Column> columnList = update.getColumns();
        StringBuffer col = new StringBuffer();
        for (int i =0;i<columnList.size();i++){
            Object obj = entity.get(columnList.get(i).getColumnName());

            col.append(columnList.get(i)).append("=");
            if (obj==null){
                col.append(obj);
            }else if (obj.getClass().getTypeName().equals("java.lang.String")){
                col.append("'").append(obj.toString()).append("'");
            }else {
                col.append(obj);
            }
            col.append(",");

        }
        return col.deleteCharAt(col.length()-1).toString();
    }
}
